import json
import re

from django.contrib.auth import login, authenticate, logout
from django.views import View
from django.http import JsonResponse
from django_redis import get_redis_connection

from ihome_team3.utils.views import LoginRequiredMixin
from users.models import User


class RegiserView(View):
    """注册接口"""

    def post(self, request):
        # 1 接收参数
        json_dict = json.loads(request.body)
        mobile = json_dict.get('mobile')
        phonecode_client = json_dict.get('phonecode')
        password = json_dict.get('password')
        password2 = json_dict.get('password2')
        if not all([mobile, phonecode_client, password]):
            return JsonResponse({'errno': "4002",
                                 'errmsg': '无数据'})
        # 2 mobile校验
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'errno': "4103",
                                 'errmsg': '参数错误'})

        # 4. password校验
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return JsonResponse({'errno': "4103",
                                 'errmsg': '参数错误'})
        # # 5. password和password2对比
        # if password ！= password2:
        #     return JsonResponse({'code': "4104",
        #                          'errmsg': '数据错误'})

        try:
            count = User.objects.filter(mobile=mobile).count()
        except Exception as e:
            return JsonResponse({"errno": "4003",
                                 "errmsg": "数据已存在"})

        # 8.sms_code检验 (链接redis数据库)
        redis_conn = get_redis_connection('verify_code')

        # 9.从redis中取值
        phonecode_server = redis_conn.get('sms_%s' % mobile)

        # 10.判断该值是否存在
        if not phonecode_server:
            return JsonResponse({'errno': "4004",
                                 'errmsg': '数据错误'})

        # 11.把redis中取得值和前端发的值对比
        if phonecode_client != phonecode_server.decode():
            return JsonResponse({'errno': "4103",
                                 'errmsg': '参数错误'})
        # 12.保存到数据库 (username password mobile)
        try:
            user = User.objects.create_user(username=mobile,
                                            password=password,
                                            mobile=mobile)
        except Exception as e:
            return JsonResponse({'errno': "4500",
                                 'errmsg': '内部错误'})
        login(request, user)

        # 生成响应对象
        response = JsonResponse({'errno': "0",
                                 'errmsg': '注册成功'})
        # 在响应对象中设置用户名信息
        # 将用户名写入到cookie中，有效期14天
        response.set_cookie('username',
                            user.mobile,
                            max_age=3600 * 24 * 14)
        # 返回响应结果
        return response


class LoginView(View):
    """登录接口"""

    def post(self, request):
        json_dict = json.loads(request.body)
        mobile = json_dict.get('mobile')
        password = json_dict.get('password')
        # 2.判断整体参数是否缺失
        if not all([mobile, password]):
            return JsonResponse({'errno': '400',
                                 'errmsg': '缺少必传参数'})
        # 3 mobile校验
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'errno': "4104",
                                 'errmsg': '用户不存在或未激活'})

        # 4. password校验
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return JsonResponse({'errno': "4106",
                                 'errmsg': '密码错误'})
        # 5.校验账号密码（认证比对）
        user = authenticate(username=mobile,
                            password=password)
        if user is None:
            return JsonResponse({'errno': "4106",
                                 'errmsg': '密码错误'})
        login(request, user)

        response = JsonResponse({'errno': "0",
                                 'errmsg': '登录成功'})
        # 在响应对象中设置用户名信息
        # 将用户名写入到cookie中，有效期14天
        response.set_cookie('mobile',
                            user.mobile,
                            max_age=3600 * 24 * 14)
        # 返回响应结果
        return response

    def get(self, request):
        cookie_mob = request.COOKIES.get('mobile')
        if cookie_mob:
            return JsonResponse({
                "errno": "0",
                "errmsg": "已登录",
                "data": {
                    "name": cookie_mob,
                    "user_id": request.user.id
                }
            })
        else:
            return JsonResponse({
                "errno": "4101",
                "errmsg": "未登录"
            })

    def delete(self, request):
        """
        实现退出登录逻辑
        由于首页中用户名是从 cookie 中读取的.
        所以退出登录时，需要将 cookie 中用户名清除.
        """
        # 清理session
        logout(request)
        # 创建response对象
        response = JsonResponse({'errno': "0",
                                 'errmsg': '已登出'})
        # 调用对象的delete_cookie方法，清除cookie
        response.delete_cookie('mobile')
        # 返回响应
        return response


class UserInfoView(LoginRequiredMixin, View):
    def get(self, request):
        user = request.user
        try:
            avatar = user.avatar
            mobile = user.mobile
            name = user.username
            user_id = user.id
            create_time = user.date_joined
            return JsonResponse({
                "data": {
                    "avatar": str(avatar),
                    "create_time": create_time,
                    "mobile": mobile,
                    "name": name,
                    "user_id": user_id
                },
                "errmsg": "OK",
                "errno": "0"
            })
        except Exception as e:
            return JsonResponse({
                "errmsg": "	数据库查询错误",
                "errno": "4001"
            })


class ChangeUserNameView(LoginRequiredMixin, View):
    def put(self, request):
        json_dict = json.loads(request.body)
        username_client = json_dict.get('name')
        if username_client is None:
            return JsonResponse({'errno': '4103',
                                 'errmsg': '参数错误'})

        if not re.match(r'^[(a-zA-Z0-9-\u4e00-\u9fa5){1}_#]{4,20}$', username_client):
            return JsonResponse({'errno': '4103',
                                 'errmsg': '参数错误'})
        try:
            user = User.objects.filter(mobile=request.user.mobile).update(username=username_client)
            return JsonResponse({
                "errno": "0",
                "errmsg": "修改成功"
            })
        except Exception as e:
            return JsonResponse({
                "errno": "4500",
                "errmsg": "内部错误"
            })


class UserAuthView(LoginRequiredMixin, View):
    def post(self, request):
        json_dict = json.loads(request.body)
        real_name = json_dict.get('real_name')
        id_card = json_dict.get('id_card')
        if not all([real_name, id_card]):
            return JsonResponse({
                "errno": "4103",
                "errmsg": "参数错误"
            })

        if not re.match("r^([a-zA-Z+\.?\·?a-zA-Z+]{2,30}$)|([\u4e00-\u9fa5+\·?\u4e00-\u9fa5+]{2,30}$)", real_name):
            return JsonResponse({
                "errno": "4103",
                "errmsg": "参数错误"
            })
        if not re.match(r"^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$|"
                    r"^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$", id_card):
            return JsonResponse({
                "errno": "4103",
                "errmsg": "参数错误"
            })
        try:
            User.objects.filter(id=request.user.id).update(real_name=real_name)
            User.objects.filter(id=request.user.id).update(id_card=id_card)
        except Exception as e:
            return JsonResponse({
                "errno": "4103",
                "errmsg": "参数错误"
            })
        return JsonResponse({
            "errno": "0",
            "errmsg": "认证信息保存成功"
        })


    def get(self, request):
        user = User.objects.get(id=request.user.id)
        try:
            real_name = user.real_name
            id_card = user.id_card
        except Exception as e:
            return JsonResponse({
                "errno": "4001",
                "errmsg": "数据库查询错误"
            })
        return JsonResponse({
            "data":{
                "real_name":real_name,
                "id_card":id_card
            },
            "errno": "0",
            "errmsg": "成功"
        })

